﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CSF.Security.Data;
using CSF.Utility.Security;
using Ict.DataAccess;

namespace CSF.Security.BLL
{
    /// <summary>
    /// 验证用户的工具类
    /// </summary>
    public static class Authenticator
    {
        private static object _locker = new object();

        private static Dictionary<string, UserSession> _userSessions = new Dictionary<string, UserSession>();

        /// <summary>
        /// 登录，并生成用户会话
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="applicationId"></param>
        /// <param name="ipAddress"></param>
        /// <param name="httpForwarded"></param>
        /// <returns></returns>
        public static string LogOn(string userName, string password, int applicationId,
            string ipAddress, string httpForwarded)
        {
            lock (_locker)
            {
                string sessionId = null;

                UserAccountBLL userBll = new UserAccountBLL();
                UserAccount user = userBll.ValidateUser(userName, password);

                if (user != null)
                {
                    UserAccountApplicationBLL uaBll = new UserAccountApplicationBLL();
                    if (uaBll.CheckUser(user.Id, applicationId))
                    {
                        UserSession session = new UserSession()
                        {
                            ApplicationId = applicationId,
                            UserId = user.Id,
                            UserName = userName,
                            IPAddress = ipAddress,
                            HttpForworded = httpForwarded,
                        };
                        UserSessionBLL logBll = new UserSessionBLL();
                        bool newsession = false;
                        // 生成SessionId，如果生成失败或重复则尝试3次
                        for (int i = 0; i < 3 && !newsession; i++)
                        {
                            DateTime loginTime = DateTime.Now;
                            sessionId = UserSessionCodec.GenerateSessionId(userName, password, ipAddress, loginTime);
                            session.SessionId = sessionId;
                            session.LoginTime = loginTime;
                            try
                            {
                                newsession = logBll.Insert(session);
                                if (newsession)
                                {
                                    _userSessions.Add(sessionId, session);
                                }
                            }
                            catch (PrimaryKeyException)
                            {
                                newsession = false;
                            }
                        }
                        // 如果生成唯一的SessionId失败，则返回空串
                        if (!newsession)
                            sessionId = null;
                    }
                }
                return sessionId;
            }
        }

        public static void LogOff(string sessionId)
        {
            lock (_locker)
            {
                if (_userSessions.ContainsKey(sessionId))
                {
                    var session = _userSessions[sessionId];
                    _userSessions.Remove(sessionId);
                    session.LogoutTime = DateTime.Now;

                    UserSessionBLL bll = new UserSessionBLL();
                    bll.Update(session, p => p.LogoutTime, p => p.SessionId == sessionId);
                }
            }
        }

        public static UserSession VerifySession(string sessionId)
        {
            lock (_locker)
            {
                if (_userSessions.ContainsKey(sessionId))
                    return _userSessions[sessionId];
                return null;
            }
        }

    }
}
